package com.sc.base.common.spring;

import com.sc.base.common.log.SpringRequestLogFilter;
import com.sc.base.common.spring.container.CustomConfigurableContainer;
import com.sc.base.common.spring.mvc.AppErrorController;
import com.sc.base.common.spring.mvc.AppExceptionHandlerController;
import com.sc.base.common.spring.mvc.BaseWebMvcConfig;
import com.sc.base.common.spring.security.SpringSecurityBaseConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.actuate.info.InfoContributor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Properties;


/**
 *
 * liuwei
 * 2019-07-19 15:03:33
 *
 *
 * */
@EnableSwagger2
public class WebApplication {

    private static final Logger logger = LoggerFactory.getLogger(WebApplication.class);


    /**
     * The default order for the core {@link InfoContributor} beans.
     */
    public static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE + 20;

    //error page
    @Bean
    public AppErrorController errorController() {
        return new AppErrorController();
    }

    @Bean
    public WebServerFactoryCustomizer webServerFactoryCustomizer() {
        return new CustomConfigurableContainer();
    }

    //exception handler
    @Bean
    public AppExceptionHandlerController appExceptionHandlerController() {
        return new AppExceptionHandlerController();
    }

    //@Bean
    public Docket api(ApplicationConstant applicationConstant) {

        if(applicationConstant.webProject && applicationConstant.isProdProfile()) {
            return new Docket(DocumentationType.SWAGGER_2).enable(false);
        } else {
            return new Docket(DocumentationType.SWAGGER_2)
                    .directModelSubstitute(LocalDate.class, java.sql.Date.class)
                    .directModelSubstitute(LocalDateTime.class, java.util.Date.class)
                    .select()
                    .apis(input -> {
                        String packageName = input.declaringClass().getPackage().getName();
                        return (packageName.startsWith("com.zkdn.")) &&
                                (packageName.contains(".web") || packageName.contains(".controller"));
                    })
                    .paths(PathSelectors.any())
                    .build();
        }
    }

    //log interceptor
    @Bean
    public SpringRequestLogFilter springRequestLogFilter() {
        return new SpringRequestLogFilter();
    }


    @Bean
    public WebMvcConfigurer baseWebMvcConfigurer() {
        return new BaseWebMvcConfig();
    }

    protected Properties loadFrom(Resource location, String prefix) throws IOException {
        String p = prefix.endsWith(".") ? prefix : prefix + ".";
        Properties source = PropertiesLoaderUtils.loadProperties(location);
        Properties target = new Properties();
        for (String key : source.stringPropertyNames()) {
            if (key.startsWith(p)) {
                target.put(key.substring(p.length()), source.get(key));
            }
        }
        return target;
    }


    @Bean
    @ConditionalOnMissingBean
    public SpringSecurityBaseConfiguration springSecurityBaseConfiguration() {
        return new SpringSecurityBaseConfiguration();
    }

}